package peer.model.transfer;

/**
 * This Codec class allows us to represent a number up to 2^(8 * k) in k bytes. Here, k = SIZE_BYTES = 5.
 * Let b be the (8 * k)-bit binary representation of an Integer. Then we can split b in k bytes. Let b[i] be
 * the i-th byte. The encoder works returning a byte array B, where B[i] = b[i] - 128.
 * The decoder works concatenating each byte B[i] + 128, to get b = (b[0])(b[1])...(b[k]).
 * @author Guido
 */

public class Codec {

	public static final Integer SIZE_BYTES = 5;
	public static final Integer BYTE = 8;

	public static void main(String[] args){
		System.out.println(decode(encode(15)));
	}


	public static byte[] encode(long size){
		byte[] encoded = new byte[SIZE_BYTES];

		for(Integer i = 0; i < SIZE_BYTES; i++){
			encoded[i] = (byte) (size >> (BYTE * (SIZE_BYTES - i - 1)));
			size ^= (encoded[i] << (BYTE * (SIZE_BYTES - i - 1)));
			encoded[i] -= 128;
		}

		return encoded;
	}

	public static long decode(byte[] array){
		long decoded = 0;

		for(Integer i = 0; i < SIZE_BYTES; i++){
			decoded = (decoded << BYTE) ^ (array[i] + 128);
		}

		return decoded;
	}
}
